#include <stdio.h>
#include <string.h>
#include "gw.h"
#include "common.h"
#include "mgw.h"
#include "CCL.h"

#define REG_REQUEST (0x10)
#define REG_RESPONSE (0x11)
#define AUTH_REQUEST (0x20)
#define AUTH_RESPONSE (0x21)

void OnCanMessage0x10(struct cclCanMessage* message);
void OnCanMessage0x20(struct cclCanMessage* message);
void OnCanMessage0x21(struct cclCanMessage* message);

void send_can_frame(unsigned char* message, int length, unsigned char frame_id);

AUTH_request rebuild_request;
AUTH_response rebuild_response;
int rebuild_count = 0;
int rebuild_count1 = 0;

void OnMeasurementPreStart()
{
    int32_t rc;
    rc = cclCanSetMessageHandler(1, cclCanMakeStandardIdentifier(0x10), &OnCanMessage0x10);
    rc = cclCanSetMessageHandler(1, cclCanMakeStandardIdentifier(0x20), &OnCanMessage0x20);
    rc = cclCanSetMessageHandler(1, cclCanMakeStandardIdentifier(0x21), &OnCanMessage0x21);
}


void OnMeasurementStart()
{
    unsigned char id[2] = { 0x00,0x96 };
    send_can_frame(id, sizeof(id), REG_REQUEST);

}

void OnCanMessage0x10(struct cclCanMessage* message)
{
    REG_request request;
    memcpy(request.ID, message->data + 1, 2);
    REG_response response = mgw_reg_process(request);
    send_can_frame((unsigned char*)&response, sizeof(response), REG_RESPONSE);
    store_gw_material(response);
    AUTH_request a_request;
    AUTH_response a_response;
    a_request = gw_auth_process();
    send_can_frame((unsigned char*)&a_request, sizeof(a_request), AUTH_REQUEST);

}

void OnCanMessage0x20(struct cclCanMessage* message)
{
    memcpy((unsigned char*)&rebuild_request+(message->data[0])*7, message->data + 1, message->dataLength - 1);
    if (rebuild_count == sizeof(rebuild_request)/7)
    {
        AUTH_response a_response = mgw_auth_process(rebuild_request);
        send_can_frame((unsigned char*)&a_response, sizeof(a_response), AUTH_RESPONSE);
    }
    else
    {
        rebuild_count++;
    }
}

void OnCanMessage0x21(struct cclCanMessage* message)
{
    memcpy((unsigned char*)&rebuild_response + (message->data[0]) * 7, message->data + 1, message->dataLength - 1);
    if (rebuild_count1 == sizeof(rebuild_response)/7)
    {
        gw_update_key(rebuild_response);
    }
    else
    {
        rebuild_count1++;
    }
}

void cclOnDllLoad()
{
    cclSetMeasurementPreStartHandler(&OnMeasurementPreStart);
    cclSetMeasurementStartHandler(&OnMeasurementStart);
}

void send_can_frame(unsigned char* message, int length, unsigned char frame_id)
{
    unsigned char buffer[8] = {0};
    int rc = 0;
    int id = cclCanMakeStandardIdentifier(frame_id);
    if (length <= 7)
    {
        buffer[0] = 0;
        memcpy(buffer + 1, message, length);
        rc = cclCanOutputMessage(1, id, 0, length + 1, buffer);
    }
    else
    {
        int frame_num = (length / 7);
        for (int i = 0; i < frame_num; ++i)
        {
            buffer[0] = i;
            memcpy(buffer + 1, message + 7 * i, 7);
            rc = cclCanOutputMessage(1, id, 0, 8, buffer);
        }
        memset(buffer, 0, 8);
        buffer[0] = frame_num;
        memcpy(buffer + 1, message + 7 * frame_num, length - (7 * frame_num));
        rc = cclCanOutputMessage(1, id, 0, length - (7 * frame_num)+1, buffer);
    }
}


/*
int main() {
    printf("start test");
    printf("\nreg\n");
    REG_request request=send_id();
    REG_response response= mgw_reg_process(request);
    store_gw_material(response);
    printf("\nauth\n");
    AUTH_request auth_request;
    AUTH_response auth_response;
    auth_request = gw_auth_process();
    auth_response = mgw_auth_process(auth_request);
    gw_update_key(auth_response);

    return 0;
}
*/